<?php

namespace org\copperforest\oak\authorization;

use \org\copperforest\oak as ct;

class RolSet
{

    static private $_roles_id = array( );
    private $id;
    private $tags = array( );
    private $serialization;

    private function __construct( $tags )
    {
        sort( $tags );
        $this->tags = $tags;
        $this->serialization = implode( '\\', $tags );
    }

    static function combine( &$tags )
    {
        sort( $tags );

        $combinations = array( );

        foreach ( $tags as $t ) {

            $new_combinations = array( );

            foreach ( $combinations as $c )
                    $new_combinations[ ] = array_merge( $c, array( $t ) );


            $combinations = array_merge( $combinations, $new_combinations,
                    array( $t ) );
        }

        return $combinations;
    }

    static function sort( &$rolset )
    {
        //indexa por el Id todos los grupos de roles
    }

    function getSubordinates()
    {
        //OJO si están creados, puede que no lo estén!!!!!!!!

        $sql = array( );
        foreach ( $this->tags as $t )
                $sql[ ] = 'serializarion like ' . ct\CT::$PDO->quote_lgr( $t,
                            '%', '%' );

        $result = ct\CT::$PDO->query( 'SELECT id, serialization FROM ct_roles WHERE ' . implode( ' OR serialization LIKE ',
                        $sql ), PDO::FETCH_NUM );

        $subordinates = array( );
        foreach ( $result as $r ) {

            if ( !isset( self::$_roles_id[ $r[ 1 ] ] ) )
                    self::$_roles_id[ $r[ 1 ] ] = $r[ 0 ];

            if ( $r[ 1 ] != $this->serialization )
                    $subordinates[ ] = new Rol( explode( '\\', $r[ 1 ] ) );
        }

        return $subordinates;
    }

    /*
      static function getInstance( $tags ){
      sort( $tags );

      $serialization = implode( '\\', $tags );

      if( !isset( self::$_roles[ $serialization ] ) ){

      $sql_serialization = ct\CT::$PDO->quote( $serialization );

      //lo mas sencillo no es obtener todos los roles del usuario y comprobar si la diferencia es vacia

      $result = ct\CT::$PDO->query( 'SELECT id FROM ct_roles WHERE serialization=' . $sql_serialization, PDO::FETCH_NUM );
      $id = $result->fetchAll( PDO::FETCH_COLUMN, 0 );
      $result->closeCursor();

      if( empty( $id ) ){

      ct\CT::$PDO->excecute( 'INSERT INTO ct_roles (serialization) VALUES (' . $sql_serialization . ')' );
      $id = ct\CT::$PDO->lastInsertId();
      }
      }

      self::$_roles[ $serialization ]= new Rol( $id, $tags );

      return self::$_roles[ $serialization ];
      }

      static function getColection( $tags ){
      sort($tags);
      $serialization = implode( '\\', $tags );

      $sql = array();
      foreach( $this->tags as $t )
      $sql[] = 'serializarion like ' . ct\CT::$PDO->quote_lgr( $t, '%', '%' );

      $result = ct\CT::$PDO->query( 'SELECT id, serialization FROM ct_roles WHERE ' . implode( ' OR serialization LIKE ', $sql ), PDO::FETCH_NUM );

      $rol = null;
      foreach($result as $r){

      if( !isset( self::$_roles[ $r[ 1 ] ] ) )
      self::$_roles[ $r[ 1 ] ] = new Rol( $r[0], explode( '\\', $r[ 1 ] ) );

      if( $r[ 1 ] == $serialization )
      $rol = self::$_roles[ $r[ 1 ] ];
      }

      $subordinates=array();
      foreach($result as $r)
      if( $r[ 1 ] !== $serialization && $rol->contains( self::$_roles[ $r[ 1 ] ] ) )
      $subordinates[] = self::$_roles[ $r[ 1 ] ];

      return array( $rol, $subordinates );
      }
     */

    function getId()
    {
        if ( empty( $this->id ) ) {

            if ( !isset( self::$_roles_id[ $this->serialization ] ) ) {

                $sql_serialization = ct\CT::$PDO->quote( $serialization );

                //lo mas sencillo no es obtener todos los roles del usuario y comprobar si la diferencia es vacia

                $result = ct\CT::$PDO->query( 'SELECT id FROM ct_roles WHERE serialization=' . $sql_serialization,
                        PDO::FETCH_NUM );
                $id = $result->fetchAll( PDO::FETCH_COLUMN, 0 );
                $result->closeCursor();

                if ( empty( $id ) ) {

                    ct\CT::$PDO->excecute( 'INSERT INTO ct_roles (serialization) VALUES (' . $sql_serialization . ')' );
                    $id = ct\CT::$PDO->lastInsertId();
                }

                self::$_roles_id[ $this->serialization ] = $id;
            }

            $this->id = self::$_roles_id[ $this->serialization ];
        }

        return $this->id;
    }

    function getTags()
    {
        return $this->tags;
    }

    function contents( $rol )
    {
        $diff = array_diff( $rol->getTags(), $this->tags );

        return empty( $diff );
    }

    //ahora 

    static function _deploy( $link )
    {
        //tengo que crear 2 tablas, una de los roles de los usuarios y otra de los grupos de roles
    }

}

?>
